import axios from "axios"
import modal from "@/plugins/modal.js"
import store from "@/store"
import {encryptObj, encryptStr} from "vue2-element-admin-plugin"

// 创建axios实例
const service = axios.create({
  baseURL: window.configObj.baseUrl || process.env.VUE_APP_BASE_URL,
  timeout: window.configObj.timeout || process.env.VUE_APP_TIME_OUT // 请求超时时间
})

// request拦截器
service.interceptors.request.use(
  config => {
    const accessToken = store.getters.accessToken
    if (accessToken) {
      config.headers.Authorization = "Bearer " + accessToken
    }

    const isEncrypt = store.getters.isEncrypt
    // 加密
    if (isEncrypt) {
      // 告诉后端此请求进行加密了
      config.headers.encrypt = "1"
      // FormData格式的数据不进行加密
      if (!(config.data instanceof FormData)) {
        config.data = {data: encryptObj(config.data)}
      } 
      for (const key in config.params) {
        if (config.params[key] !== "" && config.params[key] !== null && config.params[key] !== undefined) {
          config.params[key] = encryptStr(config.params[key])
        }
      }
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// respone拦截器
service.interceptors.response.use(
  async response => {

    const {data, config, status, request} = response
    // 如果自定义代码不是200，则判断为错误。
    if (status !== 200) {
      modal.msgError(data.message || "Error")
      return { ...data, config, responseErr: true}
    } else {
      // 二进制数据则直接返回
      if (request.responseType === "blob" || request.responseType === "arraybuffer"){
        return response
      }

      if (data.code === 200) {
        return { ...data, config}
      }
      if (data.code === 401 || data.code === 403) {
        return { ...data, config, responseErr: true}
      }
      // 用户权限变更
      if (data.code === 402) {
        modal.alertWarning(data.message).then(() => {
          window.location.reload()
        })
        return { ...data, config, responseErr: true}
      }
      modal.msgError(data.message || "Error")
      return { ...data, config, responseErr: true}
    }
  },
  error => {
    // 加入try 否则 会导致 取消重复请求时 因为无config等字段导致报错 导致取消重复请求失效
    try {
      const {config, headers, status} = error.response
      if (status === 520) { // 导出文件接口报错时与后端约定 返回状态码为 520
        // 约定好响应头添加 x-custom-header 且值为原本报错的 code
        const code = Number(headers["x-custom-header"])
        console.log("🚀 ~ code:", code)
        // 当code为401 或者 403时 触发刷新token接口或者弹框提示过期重新登录
        if (code === 401 || code === 403) {
          return { code, message: "凭证已过期，请重新登录！", config, responseErr: true}
        } else {
          modal.msgError(code === 409 ? "无权限" : (error.message || "Error"))
          return Promise.reject(error)
        }
      }
    } catch (err) {
      // console.log("🚀 ~ err:", err)
    }
  
    if (error.name !== "CanceledError") {
      modal.msgError(error.message || "Error")
    }
    return Promise.reject(error)
  }
)

export default service